package com.zhuqi;

import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.List;

/**
 * @author : ZhuQi
 * @version : 时间:2022/3/8 11:41 版本:
 */
public class ActivitiTestDemo02 {

    public static void main(String[] args) throws Exception {
        // 启动流程实例关联 BusinessKey
        // test();

        // 测试全部流程挂起
        // test01();

        // 测试单个流程实例挂起
        // test02();

        // 部署 UEL 表达式式的流程
        // test03();

        // 部创建流程实例
        // test04();

        // 启动流程实例 -》 监听器
        // test05();

        // 取消部署
        // test06();

        // 创建流程变量实例
        // test07();

        // 完成任务
        test08();
    }

    /**
     * 测试内容: 测试启动流程并保存一个 BusinessKey 和业务数据关联
     * 测试结果:
     */
    public static void test() {
        // 获取 ProcessorEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取 runtimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        // 启动 一个流程实例 并添加一个 BusinessKey
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess", "12312");
        // 输出 流程实例信息
        System.out.println("流程实例的id" + processInstance.getId());
        System.out.println("流程实例的业务id" + processInstance.getBusinessKey());
        System.out.println("流程实例名称" + processInstance.getName());
    }

    /**
     * 测试内容: 全部流程实例挂起 - 激活
     * 测试结果:
     */
    public static void test01() throws Exception {
        // 获取 ProcessEngine 对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 既然需要操作流程定义，那么就需要 获取 Repository 服务
        RepositoryService repositoryService = processEngine.getRepositoryService();

        // 通过 Repository 服务查询出来 流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("myProcess").singleResult();
        // 通过流程定义获取当前流程定义的状态 isSuspended() 该方法就描述该流程是否暂停

        boolean suspended = processDefinition.isSuspended();
        // 如果该流程定义已挂起，就激活，如果已经激活就挂起
        if (suspended) {
            // 表示当前服务已经挂起 -> 执行激活该流程
            repositoryService.activateProcessDefinitionById(processDefinition.getId(),  // 流程定义的ID
                    true,  // 是否激活
                    null); // 激活的时间
            System.out.println(processDefinition);
        } else {
            repositoryService.suspendProcessDefinitionById(processDefinition.getId(), true, null);
            System.out.println(processDefinition);
        }
    }


    /**
     * 测试内容: 测试暂停某个流程实例
     * 测试结果:
     */
    public static void test02() throws Exception {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();

        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId("12501")
                .singleResult();

        if (processInstance.isSuspended()) {
            // 挂起 -》 激活
            runtimeService.activateProcessInstanceById(processInstance.getId());
        } else {
            // 激活 -》 挂起
            runtimeService.suspendProcessInstanceById(processInstance.getId());
        }
    }

    // --------- UEL 流程部署

    /**
     * 测试内容: UEL 流程部署
     * 测试结果:
     */
    public static void test03() throws Exception {
        // 将新的 流程文件部署到数据库中
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        RepositoryService repositoryService = processEngine.getRepositoryService();

        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("bpmn/evection-variable.bpmn")
                .addClasspathResource("bpmn/evection-variable.png")
                .name("出差申请-variable")
                .deploy();
        System.out.println("deploy-id" + deploy.getId());
        System.out.println("deploy-name" + deploy.getName());
        System.out.println("deploy-类别" + deploy.getCategory());
        System.out.println("deploy-key" + deploy.getKey());
        System.out.println("deploy-租户ID" + deploy.getTenantId());
    }


    /**
     * 测试内容: 启动流程实例 并设置处理人
     * 测试结果:
     */
    public static void test04() throws Exception {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        RuntimeService runtimeService = processEngine.getRuntimeService();

        HashMap<String, Object> map = new HashMap<>();

        map.put("assignee0", "张三");
        map.put("assignee1", "张四");
        map.put("assignee2", "张五");
        // UEL-value 表达式我们要在流程实例前将其进行赋值操作
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
                "evention-uel",
                "businessKey",
                map);
        System.out.println("id" + processInstance.getId());
    }

    /**
     * 测试内容: 监听器赋值  启动流程实例
     * 测试结果:
     */
    public static void test05() throws Exception {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        RuntimeService runtimeService = processEngine.getRuntimeService();

        HashMap<String, Object> map = new HashMap<>();


        // 启动流程实例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
                "evection-listener",
                "businessKey-1");
        System.out.println("id" + processInstance.getId());
    }


    /**
     * 测试内容: 取消部署
     * 测试结果:
     */
    public static void test06() throws Exception {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();

        repositoryService.deleteDeployment("35001", true);
        repositoryService.deleteDeployment("37501", true);
    }


    /**
     * 测试内容: 启动流程变量实例
     * 测试结果:
     */
    public static void test07() throws Exception {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();

        HashMap<String, Object> map = new HashMap<>();
        map.put("user0", "朱琦");
        map.put("user1", "雷");
        map.put("user2", "香");
        map.put("user3", "财务");
        map.put("day", 5);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("evection-variable"
                , "业务数据主键"
                , map);
        System.out.println("id" + processInstance.getId());
    }

    /**
     * 测试执行业务流程
     *
     * @throws Exception
     */
    public static void test08() throws Exception {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        TaskService taskService = processEngine.getTaskService();

        Task task = taskService.createTaskQuery()
                .processInstanceId("55001")
                .taskAssignee("香")
                .singleResult();
        if (!ObjectUtils.isEmpty(task)) {
            System.out.println("任务名" + task.getName());
            System.out.println("任务id" + task.getId());
            System.out.println("任务处理人" + task.getAssignee());
            // 完成任务
            taskService.complete(task.getId());
        }

    }

    /**
     * 测试内容: 通过 RuntimeService 设置流程变量
     * 测试结果:
     */
    public static void test09() throws Exception {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        RuntimeService runtimeService = processEngine.getRuntimeService();

        runtimeService.setVariable("42507", "day", 5);
    }

}
